package com.cy.store.controller;

import com.cy.store.entity.User;
import com.cy.store.service.IUserService;
import com.cy.store.service.ex.*;
import com.cy.store.util.JsonResult;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.util.unit.DataSize;
import org.springframework.util.unit.DataUnit;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.MultipartConfigElement;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("users")
public class UserController extends BaseController{
    @Autowired
    private IUserService userService;

    @RequestMapping("reg")
    public JsonResult<Void> reg(User user) {
        // 调用业务对象执行注册
        userService.reg(user);
        // 返回
        return new JsonResult<Void>(OK);
    }

    @RequestMapping("login")
    public JsonResult<User> login(String username, String password, HttpSession session) {
        // 调用业务对象的方法执行登录，并获取返回值
        User data = userService.login(username, password);

        //登录成功后，将uid和username存入到HttpSession中
        session.setAttribute("uid", data.getUid());
        session.setAttribute("username", data.getUsername());
        // System.out.println("Session中的uid=" + getUidFromSession(session));
        // System.out.println("Session中的username=" + getUsernameFromSession(session));

        // 将以上返回值和状态码OK封装到响应结果中并返回
        return new JsonResult<User>(OK, data);
    }

    @RequestMapping("change_password")
    public JsonResult<Void> changePassword(String oldPassword,
                                           String newPassword,
                                           HttpSession session){
        //调用session.getAttribute("")获取uid和username
        Integer uid = getUidFromSession(session);
        String username = getUsernameFromSession(session);
        //调用业务对象执行修改密码
        userService.changePassword(uid,username,oldPassword,newPassword);
        //返回成功
        return new JsonResult<Void>(OK);
    }

    @GetMapping("get_by_uid")
    public JsonResult<User> getByUid(HttpSession session){
        //从HttpSession对象中获取Uid
        Integer uid = getUidFromSession(session);
        //调用业务对象执行获取数据
        User data = userService.getByUid(uid);
        //响应成功和数据
        return new JsonResult<User>(OK);
    }

    @RequestMapping("change_info")
    public JsonResult<Void> changeInfo(User user, HttpSession session) {
        // 从HttpSession对象中获取uid和username
        Integer uid = getUidFromSession(session);
        String username = getUsernameFromSession(session);
        // 调用业务对象执行修改用户资料
        userService.changeInfo(uid, username, user);
        // 响应成功
        return new JsonResult<Void>(OK);
    }

    /*投降文件大小的上限值为10MB*/
    public static final int AVATAR_MAX_SIZE = 10 * 1024 * 1024;
    /*允许上传头像的文件类型*/
    public static final List<String> AVATAR_TYPES = new ArrayList<String>();
    /*初始化允许上传的头像文件类型*/
    static {
        AVATAR_TYPES.add("images/jpg");
        AVATAR_TYPES.add("images/jpeg");
        AVATAR_TYPES.add("images/png");
        AVATAR_TYPES.add("images/bmp");
        AVATAR_TYPES.add("images/gif");
    }
    @PostMapping("change_avatar")
    public JsonResult<String> changeAvatar(
            @RequestParam("file")MultipartFile file,
            HttpSession session){
        // 判断上传的文件是否为空
        if (file.isEmpty()){
            // 是：抛出异常
            throw new FileEmptyException("上传的文件不允许为空");
        }
        // 判断上传的文件大小是否超出限制值
        if (file.getSize()>AVATAR_MAX_SIZE){
            // 是：抛出异常
            throw new FileSizeException("上传的头像文件不允许超出"+(AVATAR_MAX_SIZE/1024) + "kb" );
        }

        String contentType = file.getContentType();
        // 判断上传的文件类型是否超出限制
        if(!AVATAR_TYPES.contains(contentType)){
            // 是：抛出异常
            throw new FileTypeException("文件类型不符合");
        }
        // 获取当前项目的绝对磁盘路径
        String parent = session.getServletContext().getRealPath("upload");
        // 保存头像文件的文件夹
        File dir = new File(parent);
        if (!dir.exists()){
            dir.mkdirs();
        }
        // 保存的头像文件的文件名
        String suffix = "";
        String originalFilename = file.getOriginalFilename();
        int beginIndex = originalFilename.lastIndexOf(".");
        if (beginIndex > 0){
            suffix = originalFilename.substring(beginIndex);
        }
        String filename = UUID.randomUUID().toString() +  suffix;
        // 创建文件对象，表示保存的头像文件
        File dest = new File(dir,filename);
        // 执行保存头像文件
        try {
            //捕获异常
            file.transferTo(dest);
        }catch (IllegalStateException e){
            // 抛出异常
            throw new FileStateException("文件状态异常，可能文件被移动或删除");
        }catch (IOException e){
            //抛出异常
            throw new FileUploadIOException("上传文件时读写错误，请稍等后重试");
        }
        // 头像路径
        String avatar = "/upload" + filename;
        // 从Session中获取uid和username
        Integer uid = getUidFromSession(session);
        String username =  getUsernameFromSession(session);
        // 将头像写入到数据库中
        userService.changeAvatar(uid,username,avatar);
        // 返回成功和头像路径
        return new JsonResult<String>(OK,avatar);
        // TODO: 2022/5/23 19.38
    }
    @Bean
    public MultipartConfigElement getMultipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        // DataSize dataSize = DataSize.ofMegabytes(10);
        // 设置文件最大10M，DataUnit提供5中类型B,KB,MB,GB,TB
        factory.setMaxFileSize(DataSize.of(10, DataUnit.MEGABYTES));
        factory.setMaxRequestSize(DataSize.of(10, DataUnit.MEGABYTES));
        // 设置总上传数据总大小10M
        // TODO: 2022/5/23
        return factory.createMultipartConfig();
    }
}
